define([], function() {
    var formTableDirective = angular.module('app.directive.formTable', []);

    formTableDirective.directive('formTable', ['$timeout', function($timeout) {
        return {
            restrict: 'EA',
            replace: true,
            scope: {
                formType: '<',
                formLabel: '<',
                formPlaceholder: '<',
                formCheckbox: '<',
                formInputs: '='
            },
            template: 
                '<table class="table table-bordered table-condensed">' +
                '  <thead>' +
                '    <tr ng-if="formCheckbox">' +
                '      <th width="10%" class="text-center">' +
                '        <input type="checkbox" name="selectAll">' +
                '      </th>' +
                '      <th width="45%">{{formLabel.key}}</th>' +
                '      <th width="45%">{{formLabel.value}}</th>' +
                '    </tr>' +
                '    <tr ng-if="!formCheckbox">' +
                '      <th width="50%">{{formLabel.key}}</th>' +
                '      <th width="50%">{{formLabel.value}}</th>' +
                '    </tr>' +
                '  </thead>' +
                '  <tbody>' +
                '    <tr ng-repeat="input in formInputs">' +
                '      <td ng-if="formCheckbox" class="text-center">' +
                '        <input type="checkbox" ng-model="input.checked" ng-change="select()" ng-disabled="input.disabled">' +
                '      </td>' +
                '      <td>' +
                '        <div ng-if="formType == \'form-data\'" class="input-group input-group-sm">' +
                '          <input type="text" class="form-control" ng-model="input.name" ng-change="check(input)"' +
                '              onchange="$(this).scope().trimCheck(this)" ng-disabled="input.disabled"' +
                '              placeholder="{{formPlaceholder.key}}">' +
                '          <span class="input-group-addon">' +
                '            <select ng-model="input.type" ng-disabled="input.disabled">' +
                '              <option value="text" selected>Text</option>' +
                '              <option value="file">File</option>' +
                '            </select>' +
                '          </span>' +
                '        </div>' +
                '        <div ng-if="formType != \'form-data\'">' +
                '          <input type="text" class="form-control input-sm" ng-model="input.name" ng-change="check(input)"' +
                '              onchange="$(this).scope().trimCheck(this)" ng-disabled="input.disabled"' +
                '              placeholder="{{formPlaceholder.key}}">' +
                '        </div>' +
                '      </td>' +
                '      <td>' +
                '        <div ng-if="input.type != \'file\'">' +
                '          <input type="text" class="form-control input-sm" ng-model="input.value"' +
                '              ng-disabled="input.disabled" placeholder="{{formPlaceholder.value}}">' +
                '        </div>' +
                '        <div ng-if="input.type == \'file\'">' +
                '          <input type="file" name="{{input.name}}" ng-disabled="input.disabled">' +
                '        </div>' +
                '      </td>' +
                '    </tr>' +
                '  </tbody>' +
                '</table>',
            link: function(scope, element) {
                // checkbox
                if (scope.formCheckbox == undefined) {
                    scope.formCheckbox = true;
                }
                // label
                if (scope.formLabel == undefined) {
                    scope.formLabel = {};
                }
                if (scope.formLabel.key == undefined) {
                    scope.formLabel.key = 'Key';
                }
                if (scope.formLabel.value == undefined) {
                    scope.formLabel.value = 'Value';
                }
                // placeholder
                if (scope.formPlaceholder == undefined) {
                    scope.formPlaceholder = {};
                }
                if (scope.formPlaceholder.key == undefined) {
                    scope.formPlaceholder.key = 'New key';
                }
                if (scope.formPlaceholder.value == undefined) {
                    scope.formPlaceholder.value = 'Value';
                }

                scope.$watch('formInputs', function(newValue) {
                    syncStatus();
                });

                scope.select = function() {
                    syncStatus();
                }

                scope.check = function(input) {
                    if (/\s+/g.test(input.name)) {
                        input.name = input.name.replace(/\s+/g, '');
                    }

                    var index = scope.formInputs.indexOf(input);
                    if (index == scope.formInputs.length - 1) {
                        if (input.name != '') {
                            scope.formInputs.push({
                                name: '',
                                type: 'text',
                                value: '',
                                checked: true,
                                disabled: false
                            });
                            syncStatus();
                        }
                    } else {
                        if (input.name == '') {
                            scope.formInputs.splice(index, 1);
                            syncStatus();
                        }
                    }
                }

                scope.trimCheck = function(element) {
                    element.value = element.value.replace(/\s+/g, '');
                }

                // Initial
                if (_.isEmpty(scope.formInputs) || _.last(scope.formInputs).name != '') {
                    scope.formInputs.push({
                        name: '',
                        type: 'text',
                        value: '',
                        checked: true,
                        disabled: false
                    });
                }
                $timeout(function() {
                    element.find('input[name="selectAll"]').change(function() {
                        var selected = $(this).prop('checked');
                        scope.$apply(function() {
                            _.forEach(scope.formInputs, function(input) {
                                if (!input.disabled) {
                                    input.checked = selected;
                                }
                            });
                        });
                        syncStatus();
                    });
                    syncStatus();
                });

                function syncStatus() {
                    var selected = 0, unselected = 0;
                    _.forEach(scope.formInputs, function(input) {
                        input.checked ? selected++ : unselected++;
                    });

                    // Clear status of select all
                    element.find('input[name="selectAll"]').prop('indeterminate', '');

                    if (selected == scope.formInputs.length) {
                        element.find('input[name="selectAll"]').prop('checked', true);
                    } else if (unselected == scope.formInputs.length) {
                        element.find('input[name="selectAll"]').prop('checked', false);
                    } else {
                        element.find('input[name="selectAll"]').prop('indeterminate', true);
                    }
                }
            }
        };
    }]);

    return formTableDirective;
});
